#ifndef MP4ENC_H
#define MP4ENC_H
#include "mp4conf.h"

#define MAX_INSTANCE_NUM 32
//extern const int MAX_INSTANCE_NUM;
#define INSTANCE_ERROR 0xffffffff
#define INSTANCE_OK	   0x00000000

typedef struct nal_list{
	int nal_type;			//B\P:0 IDR:1 SPS:2 PPS:3 SEI:4 UnKnowed:-1
	int nal_offset;
	int nal_size;
	struct nal_list *next;
} nal_list;

typedef struct Mp4Context {
	uint8_t isUsed;
	//unUsed          Init       Running
	//#0->GetInstance->#1->Start->#2<->InsertBuffer
	// |               |<--Stop<--|
	// |<--Realease<---|							//SetFrameRate	只非0状态设置

	FILE * mp4_fp;									//Mp4文件句柄

    int64_t time;
    int64_t mdat_pos;
    uint64_t mdat_size;

	uint8_t * sps;
	uint32_t sps_len;
	uint8_t * pps;
	uint32_t pps_len;
    
	nal_list *video_track;							//记录帧的首部
	nal_list *tail;									//记录帧的尾部

	uint32_t video_track_size;
	
	uint32_t width;
	uint32_t height;
	
	unsigned int MEDIA_SAMPLE_DURATION;				//每一帧的延时时间
	
} Mp4Context;

void nal_list_insert_end(nal_list* new_node,Mp4Context *mov);
uint32_t nal_list_get_size(Mp4Context *mov);
nal_list * nal_list_get_head(Mp4Context *mov);
void nal_list_free(Mp4Context *mov);

static int64_t updateSize(FILE *pb, int64_t pos);
static int ff_isom_write_avcc(FILE *pfile, Mp4Context *mov);
static int mov_write_tkhd_tag(FILE *pb, Mp4Context *mov);
static int mov_write_mdhd_tag(FILE *pb,Mp4Context *mov);
static int mov_write_hdlr_tag(FILE *pb, Mp4Context *mov);
static int mov_write_vmhd_tag(FILE *pb);
static int mov_write_dref_tag(FILE *pb);
static int mov_write_dinf_tag(FILE *pb);
static int mov_write_stts_tag(FILE *pb,Mp4Context *mov);
static int mov_write_stss_tag(FILE *pb, Mp4Context *mov);
static int mov_write_stsc_tag(FILE *pb, Mp4Context *mov);
static int mov_write_stsz_tag(FILE *pb, Mp4Context *mov);
static int mov_write_stco_tag(FILE *pb, Mp4Context *mov);
static int mov_write_avcc_tag(FILE *pb, Mp4Context *mov);
static int mov_write_video_tag(FILE *pb, Mp4Context *mov);
static int mov_write_stsd_tag(FILE *pb, Mp4Context *mov);
static int mov_write_stbl_tag(FILE *pb, Mp4Context *mov);
static int mov_write_minf_tag(FILE *pb, Mp4Context *mov);
static int mov_write_mdia_tag(FILE *pb, Mp4Context *mov);
static int mov_write_edts_tag(FILE *pb, Mp4Context *mov);
static int mov_write_trak_tag(FILE *pb, Mp4Context *mov);
static int mov_write_mvhd_tag(FILE *pb, Mp4Context *mov);
static int mov_write_moov_tag(FILE *pb, Mp4Context *mov);
static int mov_write_trailer(FILE *pb,Mp4Context *mov);
static int mov_write_ftyp_tag(FILE *pb, Mp4Context * mov);
static int mov_write_mdat_tag(FILE *pb, Mp4Context *mov);
static int mov_write_header(FILE *pb,Mp4Context * mov);
static char GetBitFromSPS(char *sps,int a,int length);
static uint32_t dec_resolution(uint8_t *sps,uint32_t length,uint32_t *width,uint32_t *height);
static uint8_t * bufferToNal(uint8_t* pBuf,uint64_t lBufLen,uint64_t * lOffset,uint64_t * lNalSize,uint64_t *lNalTypeOffset);

typedef long LONG;
typedef char CHAR;
typedef unsigned long ULONG;
typedef void VOID;

extern LONG GetInstance();
extern LONG ReleaseInstance(LONG lHandle);
extern LONG StartWrite(LONG lHandle, CHAR* pszFileName);
extern LONG InsertVideoBuffer(LONG lHandle ,VOID* pBuf,ULONG lBufLen);
extern LONG InsertAudioBuffer(LONG lHandle ,VOID* pBuf,ULONG lBufLen);
extern LONG Stop(LONG lHandle);
extern LONG StartRead(LONG lHandle, CHAR* pszFileName);
extern LONG SetVideoFrameRate(LONG lHandle, LONG lFrameRate);

#endif /* MP4ENC_H */
